import { Toast } from '@/utils/tools'
import { env } from './env' 

interface IRequest{
	url: string;
	method?: "POST" | "OPTIONS" | "GET" | "HEAD" | "PUT" | "DELETE" | "TRACE" | "CONNECT";
	data?: any;
	loading?: boolean;
	other?:{
		registerKey?:string | null
	}
}

class MpRequest {
	private baseUrl: string;
	private suffix: string | null;
	private errServerText = '服务器连接异常!';
	private statusMap = new Map([
	  [400, '参数错误'],
	  [401, '需要身份认证'],
	  [403, '拒绝访问'],
	  [404, '请求错误,未找到该资源'],
	  [405, '请求方法被禁止'],
	  [406, '请求无法完成'],
	  [407, '代理请求需要授权'],
	  [408, '服务器等待客户端发送的请求时间过长'],
	  [409, '服务器处理请求时发生了冲突'],
	  [410, '请求资源被永久删除了'],
	  [413, '请求数据太大'],
	  [414, '请求url过长'],
	  [415, '服务器无法处理请求附带的媒体格式'],
	  [500, '服务器端出错！'],
	  [501, '不支持的请求'],
	  [502, '线路繁忙'],
	  [503, '系统升级维护中'],
	  [504, '请求超时！请尝试刷新页面重试'],
	]);
	private requestTaskList = new Map();
	constructor(url: string, suffix:string | null = null){
		this.baseUrl = url
		this.suffix = suffix
	}
	private generateKey(url: string, method: string, data:any = {}){
		const key = [
			url,
			method,
			JSON.stringify(data),
		].join('&')
		return key
	}
	private removeReqKey(key: string) {
	  if (this.requestTaskList.has(key)) {
	    const task = this.requestTaskList.get(key)
	    task.abort()
	    this.requestTaskList.delete(key)
	  }
	}
	public request({
		url,
		method = 'POST',
		data = {},
		loading = true,
		other = {}
	}: IRequest){
		loading && uni.showLoading({
			title: '加载中',
			mask:false
		})
		const { registerKey } = other
		return new Promise<any>((resolve, reject)=>{
			let requestKey = this.generateKey(url, method, data)
			if (this.requestTaskList.has(requestKey)){
				this.removeReqKey(requestKey)
			}
			const requestTask = uni.request({
				url: this.baseUrl + this.suffix + url,
				data,
				method,
				header: {
				'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
				'token': uni.getStorageSync("token"),
				'key': registerKey || uni.getStorageSync("key"),
				},
				 success: (res: any) => {
					this.removeReqKey(requestKey)
					let status = res.statusCode
					if (status == 200) {
						//0表示请求没有错误
						let { code = 0 } = res.data
						//特定的错误码需要清空token，比如重复登录-3
						if ([-1, '-1', 2, '-2', -3, '-3', '-5',-5].includes(code)) {
							if ([-3, '-3'].includes(code)) uni.clearStorage()
							reject(res.data)
							// uni.reLaunch({
							// 	url: '/pages/login/index',
							// })
						} else {
							if (code != 0) {
								Toast({title: res.data.msg || '服务器错误', duration: 2000})
								return reject(res.data)
							}
							resolve(res.data)
						}
					} else {
						if (this.statusMap.get(status)) {
							Toast({title: `${this.statusMap.get(status)}`, duration: 2000})
						}
						reject(this.statusMap.get(status))
					}
				},
				fail: (err) => {
					console.log('err:',err)
					//不是取消请求
					if (err?.errMsg !== "request:fail abort") {
						reject(err)
						Toast({title: this.errServerText, duration: 2000})
					}
				},
				complete: () => {
					loading && uni.hideLoading()
				}
			})
			this.requestTaskList.set(registerKey, requestTask)
		})
	}
}

const mpRequest = new MpRequest(env.BASE_URL, env.BASE_PARAMS)

export default mpRequest